package com.kevin.design.creationalPattern.singleton;

import java.util.*;
import java.util.concurrent.*;

// 懒汉式单例模式实现 负载均衡器
public class LazySingletonOfLoadBalancer {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        // 单线程环境下，懒汉单例模式，没问题
//        LoadBalancer instance1 = LoadBalancer.getInstance();
//        LoadBalancer instance2 = LoadBalancer.getInstance();
//        if (instance1 == instance2){
//            System.out.println("负载均衡器是唯一的");
//        }
//        instance1.addServer("server1");
//        instance2.addServer("server2");
//        for (int i=0;i<10;i++){
//            System.out.println("服务器：" + instance1.getServer());
//        }

        // 多线程环境下，懒汉模式会出现问题
        ExecutorService executorService = Executors.newCachedThreadPool();
        Set<LoadBalancer> set = new HashSet<>();
        for (int i=0;i<10;i++){
            Callable task = new TaskLazy();
            Future<LoadBalancer> task1 = executorService.submit(task);
            LoadBalancer loadBalance = task1.get();
            set.add(loadBalance);
        }
        if (set.size() == 1){
            System.out.println("是唯一实例true");
        }else{
            System.out.println("不是唯一实例false");
        }

    }

}

class TaskLazy implements Callable<LoadBalancer>{

    @Override
    public LoadBalancer call() throws Exception {
        System.out.println(Thread.currentThread().getName());
        return LoadBalancerLazy.getInstance();
    }
}

// 负载均衡器
class LoadBalancerLazy implements LoadBalancer{

    private static LoadBalancerLazy instance;

    private List<String> serverList;

    private LoadBalancerLazy(){
        serverList = new ArrayList<>();
    }

    synchronized public static LoadBalancerLazy getInstance(){
        if (instance == null){
            instance = new LoadBalancerLazy();
            return instance;
        }
        return instance;
    }

    public void addServer(String server){
        serverList.add(server);
    }

    public void removeServer(String server){
        serverList.remove(server);
    }

    public String getServer(){
        Random random = new Random();
        int i = random.nextInt(serverList.size());
        return serverList.get(i);
    }
}
